package com.lyxs916.network;


import com.lyxs916.common.HttpManager;
import com.lyxs916.progresscallback.ProgressCallBack;
import com.lyxs916.requestbody.HttpRequestParam;
import com.lyxs916.utils.RequestBodyUtils;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import okhttp3.RequestBody;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;

/**
 * 说明:请求网络增加订阅
 * 作者： 杨阳; 创建于：  2017-06-10  16:27
 */
public class BaseHttpRequest {


    //被订阅者
    static Observable.Transformer schedulersTransformer = new Observable.Transformer() {
        @Override
        public Object call(Object observable) {
            return ((Observable) observable).subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread());
        }
    };

    /**
     * 订阅
     *
     * @param o 被监听者，相当于网络访问
     * @param s 监听者，  相当于回调监听
     */
    public static <T> Subscription toSubscribe(Observable<T> o, Subscriber<T> s) {
        return o.compose(schedulersTransformer)
                .subscribe(s);//订阅
    }


    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //     不要传具体的url路径  如ashx,php,html， 一般在生成的时候在baseUrl已经有了（后台只写了一个接口文件）
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                 说明：Post                   2017-06-08  15:01
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    // post 有参数的请求
    public static <T> Subscription executePost(HttpCallBack<T> subscriber, String path, Map<String, String> maps) {

        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path).serviceApi.executePost(path, maps),
                new HttpSubscription<T>(subscriber));

    }

    //post 无参数的请求
    public static <T> Subscription executePost(HttpCallBack<T> subscriber, String path) {

        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path).serviceApi.executePost(path),
                new HttpSubscription<T>(subscriber));

    }

    /**
     * 上传文件与参数
     *
     * @param subscriber 订阅
     * @param path       路径
     * @param stringMap  上传的参数
     * @param fileMap    文件
     * @param <T>        返回的类型
     * @return Subscription
     */
    public static <T> Subscription uploadFiles(HttpCallBack<T> subscriber, String path,
                                               Map<String, String> stringMap, Map<String, File> fileMap) {
        //请求的集合
        Map<String, RequestBody> requestBodyMap = new HashMap<String, RequestBody>();

        //String 转换成 RequestBody 类型
        if (stringMap != null && stringMap.size() > 0) {
            for (Map.Entry<String, String> entry : stringMap.entrySet()) {
                requestBodyMap.put(entry.getKey(), RequestBodyUtils.getStringRequestBody(entry.getValue()));
            }
        }

        //File 转换成 RequestBody 类型
        if (fileMap != null && fileMap.size() > 0) {
            for (Map.Entry<String, File> entry : fileMap.entrySet()) {
                requestBodyMap.put(RequestBodyUtils.getFileKey(entry.getKey(), entry.getValue()), RequestBodyUtils.getFileRequestBody(entry.getValue()));
            }
        }

        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path).serviceApi.uploadFiles(path, requestBodyMap),
                new HttpSubscription<T>(subscriber));
    }

    /**
     * 上传文件与参数
     *
     * @param subscriber 订阅
     * @param path       路径
     * @param fileMap    文件
     * @param <T>        返回的类型
     * @return Subscription
     */
    public static <T> Subscription uploadFiles(HttpCallBack<T> subscriber, String path,
                                               Map<String, File> fileMap) {

        return uploadFiles(subscriber, path, null, fileMap);
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                 说明：get                   2017-06-08  15:01
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //get 有参数的请求
    public static <T> Subscription executeGet(HttpCallBack<T> subscriber, String path, Map<String, String> maps) {

        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path).serviceApi.executeGet(path, maps),
                new HttpSubscription<T>(subscriber));
    }


    //get 无参数的请求
    public static <T> Subscription executeGet(HttpCallBack<T> subscriber, String path) {

        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path).serviceApi.executeGet(path),
                new HttpSubscription<T>(subscriber));
    }


    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //                                 说明： 使用封装的参数                 2017-06-15  16:27
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * Post 文件上传- 带回调的请求
     *
     * @param subscriber       订阅者
     * @param path             请求路径
     * @param param            请求参数
     * @param <T>              返回的订阅类型
     * @return Subscription
     */
    public static <T> Subscription uploadFiles(HttpCallBack<T> subscriber, String path,
                                               HttpRequestParam param) {
        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path).serviceApi.uploadFiles(path, param.getPartMap()),
                new HttpSubscription<T>(subscriber));
    }


    /**
     * Post 文件上传-带回调的请求
     *
     * @param subscriber       订阅者
     * @param path             请求路径
     * @param param            请求参数
     * @param progressCallBack 进度的回调
     * @param <T>              返回的订阅类型
     * @return Subscription
     */
    public static <T> Subscription executeCallBackPost(HttpCallBack<T> subscriber, String path,
                                                       HttpRequestParam param, ProgressCallBack progressCallBack) {

        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path, progressCallBack, false).serviceApi.uploadFiles(path, param.getPartMap()),
                new HttpSubscription<T>(subscriber));
    }

    /**
     * Post 文件上传-加长超时时间的请求
     *
     * @param subscriber       订阅者
     * @param path             请求路径
     * @param param            请求参数
     * @param <T>              返回的订阅类型
     * @return Subscription
     */
    public static <T> Subscription executeLongPost(HttpCallBack<T> subscriber, String path,
                                                   HttpRequestParam param) {

        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path, null, false).serviceApi.uploadFiles(path, param.getPartMap()),
                new HttpSubscription<T>(subscriber));
    }

    /**
     * Post 文件上传-带回调加长超时时间的请求
     *
     * @param subscriber       订阅者
     * @param path             请求路径
     * @param param            请求参数
     * @param progressCallBack 进度的回调
     * @param <T>              返回的订阅类型
     * @return Subscription
     */
    public static <T> Subscription executeCallBackLongTimeOutPost(HttpCallBack<T> subscriber, String path,
                                                                  HttpRequestParam param, ProgressCallBack progressCallBack) {
        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path, progressCallBack, true).serviceApi.uploadFiles(path, param.getPartMap()),
                new HttpSubscription<T>(subscriber));
    }


    public static <T> Subscription executeGet(HttpCallBack<T> subscriber, String path,
                                              HttpRequestParam param) {
        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path).serviceApi.executeGet(path, param.getStringMap()),
                new HttpSubscription<T>(subscriber));
    }

    public static <T> Subscription executePost(HttpCallBack<T> subscriber, String path,
                                               HttpRequestParam param) {
        return toSubscribe(HttpManager.getInstance(subscriber.mHostType, subscriber.mHeadType, path ).serviceApi.executePost(path, param.getStringMap()),
                new HttpSubscription<T>(subscriber));
    }

}
